#ifndef EDGYCONFIG_H_
#define EDGYCONFIG_H_

#include <qdir.h>
#include "ui_edgyconfig.h"
#ifdef Status
#undef Status
#endif
#include "conf.h"

#include <QMainWindow>
#include <QFileDialog>
#include <QMessageBox>
#include <QDialog>
#include <QInputDialog>
#include <QX11Info>

#include "cursorselect.h"
#include "keycapture.h"
#include "customwidgets.h"
#include <edgy/configdata.h>
#include <edgy/configparser.h> // for loading the config

#include "globals.h"

/**
 * The gui uses information from the Config (conf.h) to build views. Some
 * assumptions: widgets can't be modified by the user without interaction,
 * combobox's indexes are relyable and always start from 0. This seems to be
 * the case with Qt4.
 */

class EdgyConfig : public QMainWindow, public Ui::EdgyConfigGUI {
  Q_OBJECT

public:
  EdgyConfig(QMainWindow *parent);
  ~EdgyConfig();
  
public slots: // these are reactions to gui actions as well as regular methods.
  // cursor tab
  
  /**
   * Opens a dialog and asks for the name of the new cursor set. Doesn't
   * save the set, just adds a new combo item.
   */
  void createCursorSet();
  /**
   * Renames the currently selected cursor set. Checks for overwrites of
   * existing sets and handles renaming of effects that reference this set.
   */
  void renameCursorSet();
  /**
   * Deletes the cursor set. Handles the case when an existing effect
   * references this cursor set.
   */
  void deleteCursorSet();
  /**
   * Creates a new cursor. Opens the dialog for selection and when selected,
   * adds it to the list of the currently selected cursor set.
   */
  void createCursor();
  /**
   * Opens the cursor dialog with the current cursor selected.
   */
  void editCursor();
  /**
   * Deletes the selected cursor from the list.
   */
  void deleteCursor();
  /**
   * Enables/disables the buttons associated with the cursor list.
   */
  void toggleCursorListButtons();
  /**
   * Enables/disables the buttons associated with cursor set selection.
   */
  void toggleCursorSetButtons();
  /**
   * Commits the currently-listed cursors to the config.
   */
  void saveCursors();
  /**
   * Loads the cursors in the set "name" from the current config.
   * @param name cursor set name.
   */
  void loadCursors(const QString& name);
  
  // menus tab
  
  /**
   * Prompts for a new menu name and creates it. Doesn't save it in the config.
   */
  void createMenu();
  /**
   * Renames the currently-selected menu. Handles the case, where the menu with
   * the new name already exists and when there are effects that reference the
   * menu.
   */
  void renameMenu();
  /**
   * Deletes the currently-selected menu. Handles the case, when there are
   * effects that reference this menu, offering to delete them.
   */
  void deleteMenu();
  /**
   * Enables the menu item area for editing.
   */
  void createMenuItem();
  /**
   * Enabled the menu item area for editing and populates it with the data from
   * the selected menu item in the table.
   */
  void editMenuItem();
  /**
   * Deletes the currently-selected menu item in the table.
   */
  void deleteMenuItem();
  /**
   * Opens the key capture dialog for the key action in a menu.
   */
  void openMenuKeyCaptureDlg();
  /**
   * Enables/disables the menu list widgets.
   */
  void toggleMenuListButtons();
  /**
   * Enables/disables the menu items widgets.
   */
  void toggleMenuItemsButtons();
  /**
   * Enables/disables the menus action stack.
   */
  void toggleMenuActionStack();
  /**
   * Saves the currently-selected menu item.
   */
  void saveMenuItem();
  /**
   * Loads a menu from the config with the specified name.
   * @param name name of the menu.
   */
  void loadMenu(const QString& name);
  
  // effects tab
  
  /**
   * Enables the edit effect widgets.
   */
  void createEffect();
  /**
   * Enabled the edit effect area widgets and populates them with the data
   * from the config.
   */
  void editEffect();
  /**
   * Deletes the selected effect.
   */
  void deleteEffect();
  /**
   * Reacts to clicks for the select window button in effects. Prompts the
   * user if they really want to proceed and gives instructions on how to
   * capture the window correctly. Starts the capture.
   */
  void selectWindow();
  /**
   * Checks the currently-selected window and gets its window class. Records it
   * by setting it as the text of the select window button.
   */
  void captureWindow();
  /**
   * Opens the dialog that captures the keys for the key-action effect.
   */
  void openEffectKeyCaptureDlg();
  /**
   * Enables/disables the effect list buttons.
   */
  void toggleEffectListButtons();
  /**
   * Saves the effects in the config.
   */
  void saveEffect();
  /**
   * Loads the effects from the config.
   */
  void loadEffects();
  
  // menu actions
  
  /**
   * Creates a new config. Asks if the current one needs to be saved if it's
   * been modified.
   */
  void newConfig();
  /**
   * Saves the current config. This writes it out to the file via Config.
   */
  bool saveConfig();
  /**
   * Saves the config, but first prompts the user to select a file name.
   */
  void saveConfigAs();
  /**
   * Loads the config. Prompts the user for the file name.
   */
  void loadConfig();
  
private:
  QMainWindow* parent;
  CursorSelectDlg* cursorSelectDlg;
  Config conf;
  bool configDirty;
  
  Display* xdpy;
  int xscreen;
  Window xroot;
  
  bool creatingNewEffectItem; // needed to make sure that we add, and not edit, a new item
  bool creatingNewMenuItem;
  
  // We keep this around because it stores the configdata. We could copy it, though.
  ConfigParser* parser;
  
  void clearEditMenuItemFrame();
  void clearEditEffectFrame();
  void warning(const QString& msg);
  bool setActionComboToText(QComboBox* combo, const QString& text);
  void askUnsavedChanges();
};

#endif /*EDGYCONFIG_H_*/
